import React, { Component, PropTypes } from 'react'
import AmCharts from '@amcharts/amcharts3-react'
import _ from 'underscore'
import moment from 'moment'
import { merge } from '../helper/helper'

/*报表入口*/
export default class ReactReports extends Component {
    componentDidMount() {
        this.sendRequst()
    }
    shouldComponentUpdate(nextProps, nextState) {
        const options = this.props.options;
        const trigger = options.trigger;
        var shouldTrigger = false;

        if (trigger && trigger.length) {
            trigger.forEach((i) => {
                if (this.props[i] !== nextProps[i]) {
                    shouldTrigger = true
                }
            });

            if (shouldTrigger) {
                setTimeout(() => this.sendRequst())
            }
        }

        return true
    }
    changeDate(start, end) {
        var self = this,
            options = this.props.options,
            state = this.state;

        this.sendRequst({
            startDate: start.format('YYYY-MM-DD'),
            endDate: end.format('YYYY-MM-DD')
        })
    }
    sendRequst(params) {
        const { options, isPending, getData } = this.props;
        const trigger = options.trigger;
        var shouldSend = true;

        if (!isPending) {
            let query = {
                startDate: moment().startOf('month').format('YYYY-MM-DD'),
                endDate: moment().format('YYYY-MM-DD')
            };

            if (trigger && trigger.length) {
                trigger.forEach((i) => {
                    if (i != 'trigger') {
                        if (!this.props[i]) {
                            shouldSend = false
                        }
                        query[i] = this.props[i]
                    }
                })
            }

            query = merge(query, params)

            if (shouldSend) {
                getData(query)
            }
        }
    }
    render() {
        const { options, data, isPending } = this.props;
        const getData = this.sendRequst.bind(this);

        return (
            <div className={"col-md-" + options.width}>
                <div className="box box-solid">
                    <div className="box-header with-border">
                        <h3 className="box-title" style={{ fontSize: '16px' }}>{options.title}</h3>
                        <div className="box-tools pull-right">
                            {options.datePick ? <ReactDatePick changeDate={this.changeDate} /> : ''}
                        </div>
                    </div>
                    <div className="box-body">
                        <div ref="legend"></div>
                        <div className="chart" style={{ height: options.height }}>
                            {(function () {
                                if (data && data.length) {
                                    switch (options.type) {
                                        case 'index':
                                            return <IndexChart options={options} data={data} />;
                                        case 'pie':
                                            return <PieChart options={options} data={data} />;
                                        case 'bar':
                                            return <BarChart options={options} data={data} />;
                                        case 'stacked-bar':
                                            return <StackedBarChart options={options} data={data} />;
                                        case 'line':
                                            return <LineChart options={options} data={data} />
                                    }
                                } else {
                                    return <ReLoad getData={getData} />
                                }
                            })()}
                        </div>
                    </div>
                    {(function () {
                        if (isPending && options.type != 'index') {
                            return <Loading />
                        }
                    })()}
                    {options.isLocked ? <div className="overlay overlay-lock">
                        <i className="fa fa-lock"></i>
                    </div> : ''}
                </div>
            </div>
        )
    }
}

class ReLoad extends Component {
    render() {
        return (
            <div className="overlay" onClick={() => this.props.getData()}>
                <i className="fa fa-refresh" style={{ marginLeft: '-76px', color: '#aaa', cursor: 'pointer' }}> 暂无数据</i>
            </div>
        )
    }
}

class Loading extends Component {
    render() {
        return (
            <div className="overlay">
                <i className="fa fa-refresh fa-spin"></i>
            </div>
        )
    }
}

/*指标展示*/
export class IndexChart extends Component {
    render() {
        const { options, data } = this.props;

        return (
            <div className="row">
                {(data instanceof Array) ? data.map(function (i, index) {
                    return <div key={index} className={"col-sm-6 col-md-" + (i.width || 3)}>
                        <div className={"info-box " + (i.className || 'bg-aqua')}>
                            <div className="info-box-icon">
                                <i className={"fa fa-" + (i.icon || 'globe')}></i>
                            </div>
                            <div className="info-box-content">
                                <span className="info-box-text">{i.name || '--'}</span>
                                <span className="info-box-number">{i.value || 0}</span>
                                <span className="progress-description" dangerouslySetInnerHTML={{ __html: i.description || '--' }}></span>
                            </div>
                        </div>
                    </div>
                }) : <div className={"info-box " + (data.className || 'bg-aqua')}>
                        <div className="info-box-icon">
                            <i className={"fa fa-" + (data.icon || 'globe')}></i>
                        </div>
                        <div className="info-box-content">
                            <span className="info-box-text">{data.name || '--'}</span>
                            <span className="info-box-number">{data.value || 0}</span>
                            <span className="progress-description" dangerouslySetInnerHTML={{ __html: i.description || '--' }}></span>
                        </div>
                    </div>}
            </div>
        )
    }
}

/*饼状图*/
export class PieChart extends Component {
    render() {
        const { options, data } = this.props;
        const fields = _.keys(options.keyMap);
        return (
            <div style={{ height: options.height }}>
                <AmCharts.React
                    type="pie"
                    marginLeft={50}
                    marginRight={50}
                    labelRadius={5}
                    innerRadius="50%"
                    autoResize="false"
                    startDuration="1"
                    radius="120"
                    legend={{
                        "position": "right",
                        "autoMargins": false
                    }}
                    titleField={fields[0]}
                    valueField={fields[1]}
                    theme="light"
                    balloon={{
                        "fixedPosition": true
                    }}
                    dataProvider={data}
                />
            </div>
        )
    }
}

/*柱状图*/
export class BarChart extends Component {
    render() {
        const { options, data } = this.props;
        const keyMap = options.keyMap || {};
        var keys = _.without(_.keys(data[0]), 'date', 'ageGroup') || [];
        if (Object.keys(keyMap).length) {
            keys = Object.keys(keyMap);
        }
        var temp, valueAxes = options.valueAxes ? [] : [{
            "stackType": options.stackType || "none",
            "gridAlpha": .2,
            "dashLength": 1,
            "ignoreAxisWidth": true
        }];
        const graphs = keys.map((key, index) => {
            temp = key;
            key = keyMap[key] || key;
            if (options.valueAxes) {
                valueAxes.push({
                    id: options.valueAxes[temp].id,
                    gridAlpha: options.gridAlpha[temp],
                    autoGridCount: false,
                    position: options.valueAxes[temp].position,
                });

            }
            let graph = {
                "valueAxis": options.valueAxes && options.valueAxes[temp].id,
                "type": "column",
                "fillAlphas": 0.8,
                "fillColors": options.color && options.color[temp],
                "lineColor": options.color && options.color[temp],
                "lineAlpha": 0.2,
                "valueField": key,
                "title": key,
                "clustered": options.clustered || "true",
                "labelText": "[[value]]",
                "labelFunction": function (item) {
                    return item.values.value + options.ballonType;
                },
                "balloonText": "",
                // "balloonFunction": function (item) {
                //     return item.values.value + options.ballonType;
                // }
                "bullet": options.bullet && options.bullet[temp] || "none",
                "lineThickness": options.lineThickness && options.lineThickness[temp] || 0,

            }
            if (options.type && options.type[temp]) {
                delete graph.type;
                graph.fillAlphas = 0;
                graph.lineAlpha = 0.8;
                graph.bulletSize = 5;
                graph.bulletBorderAlpha = 1;
                graph.bulletColor = '#FFF';
                graph.useLineColorForBulletBorder = true;
            }
            if (options.balloon) {
                delete graph.labelText;
                delete graph.labelFunction;
                graph.balloonFunction = item => {
                    return key + ': ' + item.values.value + (options.ballonType || '');
                }
            }
            return graph;
        });


        return (
            <div style={{ height: options.height }}>
                <AmCharts.React
                    type="serial"
                    theme="light"
                    marginLeft={options.marginLeft || 50}
                    marginBottom={50}
                    autoMarginOffset={20}
                    startDuration="0"
                    rotate={options.rotate}
                    valueAxes={valueAxes}
                    legend={
                        options.legend ? {
                            "useGraphSettings": true,
                            "position": "top"
                        } : false
                    }
                    gridAboveGraphs={true}
                    graphs={graphs}
                    rotate={options.rotate}
                    chartCursor={{
                        "cursorAlpha": 0,
                        "valueLineAlpha": 0.2
                    }}
                    categoryField={options.categoryField}
                    dataProvider={data.map((i) => {
                        let keys = _.keys(i);
                        let result = {};
                        keys.forEach((k) => {
                            result[keyMap[k] || k] = i[k]
                        })
                        return result
                    })}
                    // chartScrollbar= {{
                    //     "autoGridCount": true,
                    //     "graph": "v1",
                    //     "scrollbarHeight": 40
                    // }}
                    categoryAxis={{
                        "gridPosition": "start",
                        "gridAlpha": 0,
                        "axisAlpha": 0.2,
                        "labelRotation": options.rotateAngle,
                        "minHorizontalGap": 150
                    }}
                />
            </div>
        )
    }
}

/*柱状堆积图*/
class StackedBarChart extends Component {
    render() {
        const { options, data } = this.props;

        return (
            <div style={{ height: options.height }}>
                <AmCharts.React
                    type="serial"
                    theme="light"
                    legend={{
                        "horizontalGap": 10,
                        "maxColumns": 1,
                        "position": "right",
                        "useGraphSettings": true,
                        "markerSize": 10
                    }}
                    valueAxes={[{
                        "stackType": "regular",
                        "axisAlpha": 0.3,
                        "gridAlpha": 0
                    }]}
                    graphs={_.rest(_.keys(data[0])).map(function (i) {
                        return {
                            "balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
                            "fillAlphas": 0.8,
                            "labelText": "[[value]]",
                            "lineAlpha": 0.3,
                            "title": i,
                            "type": "column",
                            "color": "#000000",
                            "valueField": i
                        }
                    })}
                    categoryField="key"
                    categoryAxis={{
                        "gridPosition": "start",
                        "axisAlpha": 0,
                        "gridAlpha": 0,
                        "position": "left"
                    }}
                    dataProvider={data}
                />
            </div>
        )
    }
}

/*折线图*/
export class LineChart extends Component {
    render() {
        const { options, data } = this.props;
        const keys = _.without(_.keys(data[0]), 'date') || [];
        const keyMap = options.keyMap || {};
        const graphs = keys.map((key) => {
            key = keyMap[key] || key;
            return {
                "bullet": "round",
                "bulletSize": 5,
                "bulletBorderAlpha": 1,
                "bulletColor": "#FFFFFF",
                "hideBulletsCount": 50,
                "useLineColorForBulletBorder": true,
                "valueField": key,
                "title": key,
                "balloonText": (key + ": <b>[[value]]</b>"),
                "balloonFunction": function (item) {
                    return key + ": " + item.values.value + options.ballonType;
                }
            }
        });

        return (
            <div style={{ height: options.height }}>
                <AmCharts.React
                    type="serial"
                    theme="light"
                    marginLeft={30}
                    autoMarginOffset={20}
                    startDuration="1"
                    valueAxes={[{
                        "axisAlpha": 0.2,
                        "dashLength": 1,
                        "position": "left"
                    }]}
                    graphs={graphs}
                    legend={{
                        "useGraphSettings": true,
                        "position": "top"
                    }}
                    categoryField="date"
                    dataProvider={data.map((i) => {
                        let keys = _.keys(i);
                        let result = {};
                        keys.forEach((k) => {
                            result[keyMap[k] || k] = i[k]
                        })
                        return result
                    })}
                    chartCursor={{
                        "cursorAlpha": 0,
                        "zoomable": false
                    }}
                    categoryAxis={{
                        "axisColor": "#DADADA",
                        "dashLength": 1,
                        "minorGridEnabled": true,
                        "minHorizontalGap": 150
                    }}
                />
            </div>
        )
    }
}

/*时间选择器-完全版*/
class ReactDatePick extends Component {
    componentDidMount() {
        var self = this,
            changeDate = this.props.changeDate;
        $(this.refs.daterangeBtn).daterangepicker(
            {
                ranges: {
                    '今天': [moment(), moment()],
                    '昨天': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
                    '最近7天': [moment().subtract(6, 'days'), moment()],
                    '最近30天': [moment().subtract(29, 'days'), moment()],
                    '本月': [moment().startOf('month'), moment().endOf('month')],
                    '上月': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
                },
                startDate: moment().subtract(29, 'days'),
                endDate: moment(),
                maxDate: new Date()
            },
            function (start, end, name) {
                if (name == '任意范围') {
                    self.refs.reportrange.innerHTML = start.format('YYYY-MM-DD') + ' - ' + end.format('YYYY-MM-DD')
                } else {
                    self.refs.reportrange.innerHTML = name
                }
                changeDate(start, end)
            }
        )
    }
    render() {
        var dir = this.props.dir || 'right',
            warpClass = 'btn-group pull-' + dir;

        return (
            <div className={warpClass} style={dir == 'left' ? {} : { 'marginLeft': '10px' }}>
                <button type="button" className="btn btn-default pull-right btn-sm" ref="daterangeBtn" style={{ fontSize: '12px' }}>
                    <i className="fa fa-calendar"></i>
                    <span ref="reportrange" style={{ margin: '0 10px' }}>最近30天</span>
                    <i className="fa fa-caret-down"></i>
                </button>
            </div>
        )
    }
}

class WallCard extends Component {
    render() {
        var data = this.props.data;

        return (
            <div className="wall_item col-lg-3 col-md-4 col-sm-6 col-xs-12">
                <div className="box box-solid" style={data.background_color ? { backgroundColor: unescape(data.background_color) } : { backgroundImage: 'url(' + data.background + ')' }}>
                    <div className="box-header">
                        <h4>{data.logo ? <img src={data.logo} /> : ''}<a href={"/wall/" + data.id} target="_blank">{data.name}</a></h4>
                    </div>
                    <div className="box-body" style={{ color: unescape(data.font_color) }}>
                        <p>{data.description || '暂无描述'}</p>
                        <p className="box-date">最后更新：{data.date || '--'}</p>
                        <div className="clearfix"></div>
                        <a href={"/walls/" + data.id + "/edit"} className="box-setting pull-right" title="设置朋友圈"><i className="fa fa-gear"></i></a>
                        <a href={"/walls/" + data.id + "/reports"} className="box-setting pull-right" title="查看报表"><i className="fa fa-bar-chart"></i></a>
                    </div>
                    <div className="box-footer with-border">
                        <a href={"/walls/" + data.id + "/fans"} className="btn btn-flat btn-default">用户列表<strong> ({data.user_count || '--'})</strong></a>
                        <a href={"/walls/" + data.id + "/photo"} className="btn btn-flat btn-primary">全部照片<strong> ({data.photo_count || '--'})</strong></a>
                    </div>
                </div>
            </div>
        )
    }
}